﻿@inherits AdminCompontentBase
<div class="d-flex">
    <SDateTimeRangeToolbar StartDateTime="_startTime" EndDateTime="_endTime" OnUpdate="TimeRangeChange" ShowQuickChange="false" />
    <MSpacer></MSpacer>
    <div class="regular3--text caption">
        <p class="mb-1">@T("ChartPreviewTips")</p>
        <p class="mb-0 text-right">@T("YAxisUnits")：@ChartYAxisUnit</p>
    </div>
</div>
<div class="d-flex align-center justify-center">
    <MECharts Option="_option" Width="Width" Height="Height">
    </MECharts>
</div>

@code {
    [Parameter]
    public StringNumber Width { get; set; } = 761;

    [Parameter]
    public StringNumber Height { get; set; } = 223;

    [EditorRequired]
    [Parameter]
    public AlarmRuleUpsertViewModel AlarmRule { get; set; } = new();

    [Parameter]
    public string ChartYAxisUnit { get; set; } = string.Empty;

    protected override string? PageName { get; set; } = "AlarmChartBlock";

    private DateTimeOffset? _startTime;

    private DateTimeOffset? _endTime;

    private object _option = new();

    protected override void OnParametersSet()
    {
        _startTime = null;
        _endTime = null;

        FillData();
    }

    private void RenderCharts(List<string> legendData, object seriesData)
    {
        _option = new
        {
            Tooltip = new
            {
                Trigger = "axis",
            },
            Legend = new
            {
                Bottom = "0%",
                Icon = "roundRect",
                Data = legendData
            },
            Grid = new
            {
                Left = 0,
                Right = 10,
                Top = 40,
                Bottom = 30,
                ContainLabel = true
            },
            XAxis = new
            {
                Type = "time",
                BoundaryGap = false,
                AxisLine = new
                {
                    LineStyle = new
                    {
                        Color = "#E4E8F3"
                    }
                },
                AxisLabel = new
                {
                    Color = "#A3AED0"
                },
                AxisTick = new
                {
                    Show = false
                }
            },
            YAxis = new
            {
                Type = "value",
                SplitLine = new
                {
                    Show = true,
                    LineStyle = new
                    {
                        Type = "dashed"
                    }
                }
            },
            Series = seriesData
        };
    }

    private void FillData()
    {
        var timeList = new List<long>();
        var chartData = new List<AlarmPreviewChartDataItemModel>();

        if (AlarmRule.CheckFrequency.Type == AlarmCheckFrequencyTypes.FixedInterval)
        {
            timeList = GetTimeListByFixedInterval();
        }

        if (AlarmRule.CheckFrequency.Type == AlarmCheckFrequencyTypes.Cron)
        {
            timeList = GetTimeListByCron();
        }
        Random a = new Random();

        if (AlarmRule.Type == AlarmRuleTypes.Log)
        {
            foreach (var item in AlarmRule.LogMonitorItems)
            {
                var data = timeList.Select(x => new List<long> { x, a.Next(100) }).ToList()!;
                chartData.Add(new AlarmPreviewChartDataItemModel
                    {
                        Name = item.Alias,
                        Data = data
                    });
            }
        }

        if (AlarmRule.Type == AlarmRuleTypes.Metric)
        {
            foreach (var item in AlarmRule.MetricMonitorItems)
            {
                var data = timeList.Select(x => new List<long> { x, a.Next(100) }).ToList()!;
                chartData.Add(new AlarmPreviewChartDataItemModel
                    {
                        Name = item.Alias,
                        Data = data
                    });
            }
        }

        var legendData = chartData.Select(x => x.Name).ToList();
        var seriesData = chartData.Select(x => new
        {
            Name = x.Name,
            Type = "line",
            Stack = "Total",
            Data = x.Data,
            AreaStyle = new
            {
                Color = new
                {
                    ColorStops = new[] { new { Offset = 0, Color = "#ECE8FF" }, new { Offset = 1, Color = "rgba(236, 232, 255, 0)" } },
                    Global = false,
                    Type = "linear",
                    X = 0,
                    X2 = 0,
                    Y = 0,
                    Y2 = 1
                }
            },
            Smooth = true
        });
        RenderCharts(legendData, seriesData);
    }

    private List<long> GetTimeListByFixedInterval(int count = 10)
    {
        var timeList = new List<long>();
        var time = _startTime ?? DateTimeOffset.Now;

        var i = 0;
        while (CheckIsAddTime(time, i))
        {
            timeList.Add(time.ToUnixTimeMilliseconds());

            var intervalTime = AlarmRule.CheckFrequency.FixedInterval.GetIntervalTime();

            if (intervalTime.HasValue)
            {
                time = time.Add(intervalTime.Value);
            }

            i++;
        }
        return timeList;
    }

    private List<long> GetTimeListByCron(int count = 10)
    {
        var timeList = new List<long>();

        if (!CronExpression.IsValidExpression(AlarmRule.CheckFrequency.CronExpression))
        {
            return timeList;
        }

        var cronExpression = new CronExpression(AlarmRule.CheckFrequency.CronExpression);

        var timezone = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault(p => p.BaseUtcOffset == JsInitVariables.TimezoneOffset);

        if (timezone != null)
            cronExpression.TimeZone = timezone;
        var time = _startTime ?? DateTimeOffset.Now;
        var i = 0;
        while (CheckIsAddTime(time, i))
        {
            timeList.Add(time.ToUnixTimeMilliseconds());

            var nextExcuteTime = cronExpression.GetNextValidTimeAfter(time);
            if (nextExcuteTime.HasValue)
            {
                time = nextExcuteTime.Value;
            }

            i++;
        }

        return timeList;
    }

    private void TimeRangeChange((DateTimeOffset?, DateTimeOffset?) args)
    {
        (_startTime, _endTime) = args;
        FillData();
    }

    public int GetMonth(DateTime date1, DateTime date2)
    {
        int year1 = date1.Year;
        int year2 = date2.Year;
        int month1 = date1.Month;
        int month2 = date2.Month;
        int months = 12 * (year2 - year1) + (month2 - month1);
        return months;
    }

    private bool CheckIsAddTime(DateTimeOffset time, int i)
    {
        if (i > 300)
        {
            return false;
        }

        if (_endTime.HasValue && time <= _endTime)
        {
            return true;
        }

        if (!_endTime.HasValue && i < 10)
        {
            return true;
        }

        return false;
    }
}
